//
//  Range+SGExtension.swift
//  QingLiuSwift
//
//  Created by xyanl on 2024/10/22.
//  Copyright © 2024 考拉🐨. All rights reserved.
//

import Foundation

extension Range<String.Index> {
    /// Range 转 NSRange
    /// - Parameter string: 字符串
    /// - Returns: NSRange
    func toNSRange(in string: String) -> NSRange {
        NSRange(self, in: string)
    }
}

extension NSRange {
    /// NSRange 转 Range
    /// - Parameter string: 字符串
    /// - Returns: Range
    func toRange(in string: String) -> Range<String.Index>? {
        string.toRange(self)
    }
}


extension String {
    
    /// 查找子字符串在父字符串中的所有位置
    /// - Parameter substring: 字符串
    /// - Returns: 返回位置数组,NSRange的字符串类型
    func inRange(of subString: String) -> [NSRange] {
        var nsRanges: [NSRange] = []
        var tempString: NSString = NSString(string: self)
        var count = 0
        
        while tempString.contains(subString) {
            var nsRange = tempString.range(of: subString)
            
            tempString = tempString.replacingCharacters(in: nsRange, with: "") as NSString
            
            nsRange = NSMakeRange(nsRange.location + subString.count * count, nsRange.length)
            
            nsRanges.append(nsRange)
            count += 1
        }
        
        return nsRanges
    }
    
    func toNSRange(_ range: Range<String.Index>) -> NSRange {
        guard let from = range.lowerBound.samePosition(in: utf16), let to = range.upperBound.samePosition(in: utf16) else {
            return NSMakeRange(0, 0)
        }
        return NSMakeRange(utf16.distance(from: utf16.startIndex, to: from), utf16.distance(from: from, to: to))
    }
    
    func toRange(_ range: NSRange) -> Range<String.Index>? {
        guard let from16 = utf16.index(utf16.startIndex, offsetBy: range.location, limitedBy: utf16.endIndex) else {
            return nil
        }
        
        guard let to16 = utf16.index(from16, offsetBy: range.length, limitedBy: utf16.endIndex) else { return nil }
        
        guard let from = String.Index(from16, within: self) else {
            return nil
        }
        
        guard let to = String.Index(to16, within: self) else {
            return nil
        }
        
        return from ..< to
    }
}
